#pragma once
#include"Logger.hpp"
#include"Route.hpp"
#include"InetAddr.hpp"
#include<iostream>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<cstdlib>
#include<cstring>
#include <arpa/inet.h>
#include<strings.h>
#include<functional>


const int gsockiddefault=-1;

// using callback_t=std::function<std::string \
//     (const std::string& word,const std::string &whoip,uint16_t whoport)>;

using callback_t =std::function<void \
    (int sockid,std::string message,InetAddr addr)>;

class ChatServer
{
public:
    ChatServer(uint16_t port,callback_t cb)
        :_sockid(gsockiddefault),
        _port(port),
        _cb(cb),
        _isrunning(false)
    {}
    void Init()
    {
        _sockid=socket(AF_INET,SOCK_DGRAM,0);
        if(_sockid<0)
        {
            LOG(Loglevel::FATAL)<<"create socket error";
            exit(1);
        }
        LOG(Loglevel::INFO)<<"create socket success: "<<_sockid;

        InetAddr local(_port);
        int n=bind(_sockid,local.Addr(),local.Length());
        if(n<0)
        {
            LOG(Loglevel::FATAL)<<"bind socket error";
            exit(1);
        }
        LOG(Loglevel::INFO)<<"bind socket success: "<<_sockid;

    }
    void Start()
    {
        _isrunning=true;
        while(_isrunning)
        {
            char buffer[1024];
            buffer[0]=0;
            struct sockaddr_in peer;
            socklen_t len=sizeof(peer);
            ssize_t n=recvfrom(_sockid,buffer,sizeof(buffer),
                0,(struct sockaddr*)&peer,&len);
            if(n > 0)
            {
                // 约定: 聊天消息
                buffer[n]=0;
                //现在这里都没有执行哦
                InetAddr client(peer);
                // 谁发的client
                LOG(Loglevel::DEBUG)<<"get a client info # " 
                    <<"["<<client.Ip()<<"-"<<client.Port()<<": "<<buffer;

                std::string message = buffer;

                _cb(_sockid, message, client);
            }
        }
        _isrunning=false;
    }
    void Stop()
    {
        _isrunning=false;
    }
    ~ChatServer()
    {}
private:
    int _sockid;
    uint16_t _port;
    callback_t _cb;
    bool _isrunning;
};